/*******************************************************************************
 * Copyright (c) 2011 Prometheus Consulting
 *
 *     Licensed under the Apache License, Version 2.0 (the "License"); you may
 *     not use this file except in compliance with the License. You may obtain
 *     a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *     WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *     License for the specific language governing permissions and limitations
 *     under the License.
 *******************************************************************************/
package nz.co.senanque.perspectivemanager;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import nz.co.senanque.vaadinsupport.I18n.I18nCaptionHelper;
import nz.co.senanque.vaadinsupport.permissionmanager.ChangeUserEvent;
import nz.co.senanque.vaadinsupport.permissionmanager.PermissionManager;
import nz.co.senanque.vaadinsupport.permissionmanager.PermissionManager.ChangeUserListener;
import nz.co.senanque.vaadinsupport.viewmanager.ViewManaged;
import nz.co.senanque.vaadinsupport.viewmanager.ViewManager;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.core.io.Resource;

import com.vaadin.Application;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.MenuBar.Command;
import com.vaadin.ui.MenuBar.MenuItem;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.BaseTheme;

/**
 * @author Roger Parkinson
 *
 */
public class MainLayout extends CustomComponent implements InitializingBean,ViewManaged, MessageSourceAware {

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private HorizontalLayout bodyLayout;
	@AutoGenerated
	private Panel panel_2;
	@AutoGenerated
	private VerticalLayout ApplicationlBodyLayout;
	@AutoGenerated
	private Panel panel_1;
	@AutoGenerated
	private VerticalLayout ApplicationIconContainer;
	@AutoGenerated
	private HorizontalLayout headingButtonslLayout;
	@AutoGenerated
	private Label loggedInAs;
	@AutoGenerated
	private MenuBar menuBar_1;
	@AutoGenerated
	private HorizontalLayout headingLayout;
	@AutoGenerated
	private Label titleLabel;
	@AutoGenerated
	private Embedded embedded_1;

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	private static final long serialVersionUID = 5500920090791031142L;
	@Autowired PermissionManager m_permissionManager;
	@Autowired BundleListenerImpl m_bundleListenerImpl;
	private Application m_application;
	private List<MenuBar.MenuItem> m_added = new ArrayList<MenuBar.MenuItem>();
	private Window about;
	private Blackboard m_blackboard = new Blackboard();

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
	private MessageSourceAccessor m_messageSourceAccessor;
	private ViewManager m_viewManager;

	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public MainLayout() {
		buildMainLayout();
		setCompositionRoot(mainLayout);

		// TODO add user code here
		titleLabel.addStyleName("v-textfield-align-right");
		about = new Window("About");
        // ...and make it modal
        about.setModal(true);
        // Configure the windows layout; by default a VerticalLayout
        VerticalLayout layout = (VerticalLayout) about.getContent();
        layout.setMargin(true);
        layout.setSpacing(true);

        // Add some content; a label and a close-button
        Label message = new Label("This is the Madura Perspective Demo.");
        about.addComponent(message);

        Button close = new Button("Close", new Button.ClickListener() {
            private static final long serialVersionUID = -2514624721741454593L;

			// inline click-listener
            public void buttonClick(ClickEvent event) {
                // close the window by removing it from the parent window
                (about.getParent()).removeWindow(about);
            }
        });
        // The components added to the window are actually added to the window's
        // layout; you can use either. Alignments are set using the layout
        layout.addComponent(close);
        layout.setComponentAlignment(close, Alignment.TOP_RIGHT);
	}
	public void afterPropertiesSet() throws Exception {
		getPermissionManager().addListener(new ChangeUserListener(){

			public void changeUser(ChangeUserEvent arg0) {
				String currentValue = (String)loggedInAs.getValue();
				loggedInAs.addStyleName("v-textfield-align-right");
				loggedInAs.setValue(m_messageSourceAccessor.getMessage(
							(String)loggedInAs.getValue(), 
							new Object[]{arg0.getCurrentUser()},currentValue));
			}});
		final MenuBar.MenuItem file = menuBar_1.addItem(m_messageSourceAccessor.getMessage("file","File"), null);
		file.addItem("Logout", new Command(){

			private static final long serialVersionUID = -1805734819451947967L;

			public void menuSelected(MenuItem selectedItem) {
				getViewManager().logout();
				
			}});
		final MenuBar.MenuItem help = menuBar_1.addItem(m_messageSourceAccessor.getMessage("help","Help"), null);
		help.addItem(m_messageSourceAccessor.getMessage("about","About"), new Command(){


			private static final long serialVersionUID = -1816887051826395057L;

			public void menuSelected(MenuItem selectedItem) {
                if (about.getParent() != null) {
                    // window is already showing
                    getWindow().showNotification(
                            "Window is already open");//should not show...
                } else {
                    // Open the subwindow by adding it to the parent
                    // window
                    getWindow().addWindow(about);
                }
			}});

		I18nCaptionHelper.switchCaptions(this,m_messageSourceAccessor);
	}
	
	private void setupSubApplication(final SubApplication subApplication)
	{
		Button b = new Button(subApplication.getCaption());
        b.setDescription(subApplication.getDescription());
        Resource icon = subApplication.getIcon();
        if (icon != null)
        {
        	b.setIcon(new SpringResource(icon,getApplication()));
        }
        b.setStyleName(BaseTheme.BUTTON_LINK);
        b.addListener(new Button.ClickListener() {
        	
			private static final long serialVersionUID = -3114725488591342579L;
			private App m_app=null;
			
			public void buttonClick(ClickEvent event) {
				
				Iterator<Component> it = ApplicationlBodyLayout.getComponentIterator();
				while (it.hasNext())
				{
					Component component = it.next();
					ApplicationlBodyLayout.removeComponent(component);
					component.detach();
					break;
				}
				if (m_app == null)
				{
					m_app = subApplication.getAppFactory().createApp(m_blackboard);
				}
				ApplicationlBodyLayout.addComponent(m_app.getComponentContainer());
				titleLabel.setValue(subApplication.getDescription());
				MenuCloner.clean(menuBar_1,m_added);
				MenuCloner.merge(menuBar_1, m_app.getMenuBar(), m_added);
				menuBar_1.requestRepaint();
			}
		}); // react to clicks
        ApplicationIconContainer.addComponent(b);
	}

	public PermissionManager getPermissionManager() {
		return m_permissionManager;
	}

	public void setPermissionManager(PermissionManager permissionManager) {
		m_permissionManager = permissionManager;
	}

	public BundleListenerImpl getBundleListenerImpl() {
		return m_bundleListenerImpl;
	}

	public void setBundleListenerImpl(BundleListenerImpl bundleListenerImpl) {
		m_bundleListenerImpl = bundleListenerImpl;
	}

	public Application getApplication() {
		return m_application;
	}

	public void setApplication(Application application) {
		m_application = application;
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("800px");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("800px");
		setHeight("-1px");
		
		// headingLayout
		headingLayout = buildHeadingLayout();
		mainLayout.addComponent(headingLayout);
		
		// headingButtonslLayout
		headingButtonslLayout = buildHeadingButtonslLayout();
		mainLayout.addComponent(headingButtonslLayout);
		
		// bodyLayout
		bodyLayout = buildBodyLayout();
		mainLayout.addComponent(bodyLayout);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHeadingLayout() {
		// common part: create layout
		headingLayout = new HorizontalLayout();
		headingLayout.setStyleName("heading");
		headingLayout.setImmediate(false);
		headingLayout.setWidth("100.0%");
		headingLayout.setHeight("40px");
		headingLayout.setMargin(false);
		
		// embedded_1
		embedded_1 = new Embedded();
		embedded_1.setImmediate(false);
		embedded_1.setWidth("-1px");
		embedded_1.setHeight("-1px");
		embedded_1.setSource(new ThemeResource("images/logo.png"));
		embedded_1.setType(1);
		embedded_1.setMimeType("image/gif");
		headingLayout.addComponent(embedded_1);
		
		// titleLabel
		titleLabel = new Label();
		titleLabel.setStyleName("heading-words");
		titleLabel.setImmediate(false);
		titleLabel.setWidth("470px");
		titleLabel.setHeight("-1px");
		titleLabel.setValue("title");
		headingLayout.addComponent(titleLabel);
		headingLayout.setComponentAlignment(titleLabel, new Alignment(34));
		
		return headingLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHeadingButtonslLayout() {
		// common part: create layout
		headingButtonslLayout = new HorizontalLayout();
		headingButtonslLayout.setStyleName("heading-buttons");
		headingButtonslLayout.setImmediate(false);
		headingButtonslLayout.setWidth("100.0%");
		headingButtonslLayout.setHeight("26px");
		headingButtonslLayout.setMargin(false);
		
		// menuBar_1
		menuBar_1 = new MenuBar();
		menuBar_1.setImmediate(false);
		menuBar_1.setWidth("-1px");
		menuBar_1.setHeight("-1px");
		headingButtonslLayout.addComponent(menuBar_1);
		
		// loggedInAs
		loggedInAs = new Label();
		loggedInAs.setStyleName("heading-button");
		loggedInAs.setImmediate(false);
		loggedInAs.setWidth("-1px");
		loggedInAs.setHeight("-1px");
		loggedInAs.setValue("logged.in.as");
		headingButtonslLayout.addComponent(loggedInAs);
		headingButtonslLayout.setComponentAlignment(loggedInAs, new Alignment(
				34));
		
		return headingButtonslLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildBodyLayout() {
		// common part: create layout
		bodyLayout = new HorizontalLayout();
		bodyLayout.setImmediate(false);
		bodyLayout.setWidth("100.0%");
		bodyLayout.setHeight("-1px");
		bodyLayout.setMargin(false);
		
		// panel_1
		panel_1 = buildPanel_1();
		bodyLayout.addComponent(panel_1);
		
		// panel_2
		panel_2 = buildPanel_2();
		bodyLayout.addComponent(panel_2);
		bodyLayout.setComponentAlignment(panel_2, new Alignment(6));
		
		return bodyLayout;
	}

	@AutoGenerated
	private Panel buildPanel_1() {
		// common part: create layout
		panel_1 = new Panel();
		panel_1.setImmediate(false);
		panel_1.setWidth("150px");
		panel_1.setHeight("-1px");
		
		// ApplicationIconContainer
		ApplicationIconContainer = new VerticalLayout();
		ApplicationIconContainer.setImmediate(false);
		ApplicationIconContainer.setWidth("100.0%");
		ApplicationIconContainer.setHeight("100.0%");
		ApplicationIconContainer.setMargin(false);
		panel_1.setContent(ApplicationIconContainer);
		
		return panel_1;
	}

	@AutoGenerated
	private Panel buildPanel_2() {
		// common part: create layout
		panel_2 = new Panel();
		panel_2.setImmediate(false);
		panel_2.setWidth("650px");
		panel_2.setHeight("-1px");
		
		// ApplicationlBodyLayout
		ApplicationlBodyLayout = new VerticalLayout();
		ApplicationlBodyLayout.setImmediate(false);
		ApplicationlBodyLayout.setWidth("100.0%");
		ApplicationlBodyLayout.setHeight("100.0%");
		ApplicationlBodyLayout.setMargin(false);
		panel_2.setContent(ApplicationlBodyLayout);
		
		return panel_2;
	}

	public void setMessageSource(MessageSource messageSource) {
		m_messageSourceAccessor = new MessageSourceAccessor(messageSource);
	}
	public void setViewManager(ViewManager viewManager) {
		m_viewManager = viewManager;
		setApplication(viewManager.getApplication());
		for (SubApplication subApplication: getBundleListenerImpl().getSubApplicationValues())
		{
			setupSubApplication(subApplication);
		}
		
	}
	public ViewManager getViewManager() {
		return m_viewManager;
	}

}
